package com.fat.config;

import com.fat.annotation.NoAdmin;
import com.fat.annotation.NoToken;
import com.fat.entity.User;
import com.fat.service.IUserService;
import com.fat.utils.JwtUtil;
import com.fat.utils.UserHolder;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

/**
 * jwt令牌校验的拦截器
 */
@Component
public class JwtTokenInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(JwtTokenInterceptor.class);

    @Resource
    private IUserService userService;

    @Resource
    private JwtUtil jwtUtil;

    // 令牌自定义标识
    @Value("${token.header}")
    private String header;

    /**
     * 校验jwt
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        //判断当前拦截到的是Controller的方法还是其他资源
        if (!(handler instanceof HandlerMethod)) {
            //当前拦截到的不是动态方法，直接放行
            return true;
        }

        //判断方法上是否有NoToken注解
        HandlerMethod handlerMethod = (HandlerMethod) handler;
        NoToken noToken = handlerMethod.getMethod().getAnnotation(NoToken.class);
        if (noToken != null) {
            //方法上有NoToken注解，直接放行
            return true;
        }

        //1、从请求头中获取令牌
        String token = request.getHeader(header);

        //2、校验令牌
        try {
            log.info("Jwt校验:{}", token);
            String id = jwtUtil.getMemberIdByJwtToken(token);
            String username = jwtUtil.getMemberNameByJwtToken(token);
            if (!StringUtils.isEmpty(id) && !StringUtils.isEmpty(username)) {
                User user = userService.getById(id);
                // 判断是否有管理员权限
                NoAdmin noAdmin = handlerMethod.getMethod().getAnnotation(NoAdmin.class);
                if (noAdmin != null || user.getIsAdmin() == 1) {
                    log.info("当前用户信息:{}", user);
                    //将用户信息存入ThreadLocal
                    UserHolder.saveUser(user);
                    //3、通过，放行
                    return true;
                }
                //没有管理员权限
                response.setStatus(500);
                response.setContentType("application/json;charset=utf-8");
                response.getWriter().write("{\"code\":500,\"msg\":\"权限不够哦！\"}");
                return false;
            }
            //4、不通过，响应401状态码
            response.setStatus(401);
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write("{\"code\":401,\"msg\":\"请先登录\"}");
            return false;
        } catch (Exception ex) {
            //4、不通过，响应401状态码
            response.setStatus(401);
            response.setContentType("application/json;charset=utf-8");
            response.getWriter().write("{\"code\":401,\"msg\":\"" + ex.getMessage() + "\"}");
            return false;
        }
    }
}
